<template>
  <my-dialog
    dialog-class="cropper-dialog"
    ref="dialogRef"
    :can-close-by-click-outside="false"
    @close="handleCloseByFork"
  >
    <div class="show-preview">
      <VueCropper
        ref="vcropperRef"
        :img="option.img"
        :outputSize="option.outputSize"
        :outputType="option.outputType"
        :info="option.info"
        :canScale="option.canScale"
        :autoCrop="option.autoCrop"
        :autoCropWidth="option.autoCropWidth"
        :autoCropHeight="option.autoCropHeight"
        :fixed="option.fixed"
        :fixedNumber="option.fixedNumber"
        :full="option.full"
        :fixedBox="option.fixedBox"
        :canMove="option.canMove"
        :canMoveBox="option.canMoveBox"
        :original="option.original"
        :centerBox="option.centerBox"
        :height="option.height"
        :infoTrue="option.infoTrue"
        :maxImgSize="option.maxImgSize"
        :enlarge="option.enlarge"
        :mode="option.mode"
        @realTime="realTime"
      />
    </div>

    <div class="cropper-action">
      <el-icon @click="handleRotateLeft"><RefreshLeft /></el-icon>
      <span @click="handleFinishCrop">确认</span>
      <el-icon @click="handleRotateRight"><RefreshRight /></el-icon>
    </div>
  </my-dialog>
</template>

<script lang="ts" setup>
import MyDialog from '@/components/dialog/MyDialog.vue'
import { ref, watch } from 'vue'

// ====== props/emit
const props = defineProps({
  img: String
})
const emit = defineEmits(['getPreview', 'finishCrop', 'closeByFork'])

// ====== data
const dialogRef = ref<any>(null)
const vcropperRef = ref<any>(null)
const option = ref<any>({
  img: '', // 裁剪图片的地址
  outputSize: 1, // 裁剪生成图片的质量(可选0.1 - 1)
  outputType: 'png', // 裁剪生成图片的格式（jpeg || png || webp）
  info: true, // 图片大小信息
  canScale: true, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth: 300, // 默认生成截图框宽度
  autoCropHeight: 300, // 默认生成截图框高度
  fixed: true, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例
  full: false, // false按原比例裁切图片，不失真
  fixedBox: false, // 固定截图框大小，不允许改变
  canMove: false, // 上传图片是否可以移动
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  height: true, // 是否按照设备的dpr 输出等比例图片
  infoTrue: false, // true为展示真实输出图片宽高，false展示看到的截图框宽高
  maxImgSize: 3000, // 限制图片最大宽度和高度
  enlarge: 1, // 图片根据截图框输出比例倍数
  mode: '100%' // 图片默认渲染方式
})

// ====== watch
watch(
  () => props.img,
  () => {
    option.value.img = props.img
  }
)

// ====== methods
const realTime = (data: any) => {
  // 实时预览函数
  const imgAxis = vcropperRef.value?.getImgAxis()
  const cropAxis = vcropperRef.value?.getCropAxis()
  let cropImgX = cropAxis.x1 - imgAxis.x1
  let cropImgY = cropAxis.y1 - imgAxis.y1
  data.x = cropImgX
  data.y = cropImgY

  emit('getPreview', data)
}
const handleRotateLeft = () => {
  vcropperRef.value?.rotateLeft()
}
const handleRotateRight = () => {
  vcropperRef.value?.rotateRight()
}
const handleFinishCrop = () => {
  // base64: getCropData; blob: getCropBlob
  vcropperRef.value?.getCropBlob((data: any) => {
    emit('finishCrop', data)
  })
}
const showCropper = () => {
  dialogRef.value?.openDialog()
}
const hiddenCropper = (cb?: () => void) => {
  cb && cb()
  dialogRef.value?.closeDialog()
}
const handleCloseByFork = () => {
  emit('closeByFork')
}

// ====== expose
defineExpose({ showCropper, hiddenCropper })
</script>

<style lang="less" scoped>
@import '@/assets/css/common.less';

.show-preview {
  width: 100%;
  height: 500px;
  width: 500px;
  margin: auto;
}
.cropper-action {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 30px;
  color: @primary-color;
  cursor: pointer;
  padding: 20px 40px;

  span {
    font-size: 22px;
  }
}
</style>
